package com.chuangjiangx.member.stored.ddd.domain.model;

import com.chuangjiangx.dddbase.Repository;
import com.chuangjiangx.domain.shared.model.PayEntry;
import com.chuangjiangx.domain.shared.model.PayTerminal;
import com.chuangjiangx.domain.shared.model.PayType;
import com.chuangjiangx.member.stored.dao.mapper.InMbrOrderMapper;
import com.chuangjiangx.member.stored.dao.model.InMbrOrder;
import com.chuangjiangx.member.stored.dao.model.InMbrOrderExample;
import com.chuangjiangx.member.coupon.ddd.domain.model.MbrHasCouponId;
import com.chuangjiangx.member.basic.ddd.domain.model.MemberId;
import com.chuangjiangx.member.basic.ddd.domain.model.MerchantId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @author cj-ch
 * @date 2018/4/8 下午5:17
 */
@Component
public class MbrOrderRepository implements Repository<MbrOrder,MbrOrderId> {

    @Autowired
    private InMbrOrderMapper inMbrOrderMapper;

    @Override
    public MbrOrder fromId(MbrOrderId mbrOrderId) {
        InMbrOrder inMbrOrder = inMbrOrderMapper.selectByPrimaryKey(mbrOrderId.getId());
        return inMbrOrder == null ? null : wrap(inMbrOrder);
    }

    public MbrOrder fromOrderNumber(String orderNumber) {
        InMbrOrderExample example = new InMbrOrderExample();
        example.createCriteria()
                .andOrderNumberEqualTo(orderNumber);
        List<InMbrOrder> inMbrOrders = inMbrOrderMapper.selectByExample(example);
        return inMbrOrders.isEmpty() ? null : wrap(inMbrOrders.get(0));
    }

    /**
     * 根据order_pay表的订单编号查询
     * @param orderPayNumber
     * @return
     */
    public MbrOrder fromOrderPayNumber(String orderPayNumber) {
        InMbrOrderExample example = new InMbrOrderExample();
        example.createCriteria()
                .andOrderPayNumberEqualTo(orderPayNumber);
        List<InMbrOrder> inMbrOrders = inMbrOrderMapper.selectByExample(example);
        return inMbrOrders.isEmpty() ? null : wrap(inMbrOrders.get(0));
    }

    /**
     * 根据卡券id查找订单
     * @param mbrHasCouponId 领取卡券id
     * @return
     */
    public MbrOrder fromMbrHasCouponId(Long mbrHasCouponId) {
        InMbrOrderExample example = new InMbrOrderExample();
        example.createCriteria().andMbrHasCouponIdEqualTo(mbrHasCouponId);
        List<InMbrOrder> inMbrOrders = inMbrOrderMapper.selectByExample(example);
        return inMbrOrders.isEmpty() ? null : wrap(inMbrOrders.get(0));
    }

    @Override
    public void update(MbrOrder mbrOrder) {
        InMbrOrder in = unbox(mbrOrder);
        in.setUpdateTime(new Date());
        inMbrOrderMapper.updateByPrimaryKeySelective(in);
    }

    @Override
    public void save(MbrOrder mbrOrder) {
        InMbrOrder in = unbox(mbrOrder);
        in.setCreateTime(new Date());
        inMbrOrderMapper.insertSelective(in);
        mbrOrder.setId(new MbrOrderId(in.getId()));
    }
    private MbrOrder wrap(InMbrOrder in){
        Optional<InMbrOrder> optional = Optional.of(in);
        MbrOrder order = new MbrOrder(
                in.getOrderNumber(),
                MbrOrderType.of(in.getType()),
                new MerchantId(in.getMerchantId()),
                in.getMerchantUserId(),
                in.getStoreId(),
                in.getStoreUserId(),
                new MemberId(in.getMemberId()),
                optional.map(InMbrOrder::getOrderAmount).orElse(BigDecimal.ZERO),
                optional.map(InMbrOrder::getDiscountAmount).orElse(BigDecimal.ZERO),
                optional.map(InMbrOrder::getPaidAmount).orElse(BigDecimal.ZERO),
                optional.map(InMbrOrder::getRefundAmount).orElse(BigDecimal.ZERO),
                in.getPaidTime(),
                in.getRefundTime(),
                in.getMbrHasCouponId() == null ? null : new MbrHasCouponId(in.getMbrHasCouponId()),
                MbrOrderStatus.of(in.getStatus()),
                in.getPayEntry() == null ? null : PayEntry.getPayEntry(in.getPayEntry()),
                in.getPayType() == null ? null : PayType.getPayType(in.getPayType()),
                in.getRemark(),
                in.getPayTerminal() == null ? null : PayTerminal.getPayTerminal(in.getPayTerminal()),
                in.getOrderPayNumber(),
                in.getMbrRechargeRuleId() == null ? null : new MbrRechargeRuleId(in.getMbrRechargeRuleId())
        );
        if(in.getId() != null){
            order.setId(new MbrOrderId(in.getId()));
        }
        return order;
    }

    private InMbrOrder unbox(MbrOrder order){
        InMbrOrder in = new InMbrOrder();
        in.setOrderNumber(order.getOrderNumber());
        in.setType(order.getType().value);
        in.setMerchantId(order.getMerchantId().getId());
        in.setMerchantUserId(order.getMerchantUserId());
        in.setStoreId(order.getStoreId());
        in.setStoreUserId(order.getStoreUserId());
        in.setMemberId(order.getMemberId().getId());
        in.setOrderAmount(order.getOrderAmount());
        in.setDiscountAmount(order.getDiscountAmount());
        in.setPaidAmount(order.getPaidAmount());
        in.setRefundAmount(order.getRefundAmount());
        in.setPaidTime(order.getPaidTime());
        in.setRefundTime(order.getRefundTime());
        in.setMbrHasCouponId(order.getMbrHasCouponId() == null ? null : order.getMbrHasCouponId().getId());
        in.setStatus(order.getStatus().value);
        in.setPayEntry(order.getPayEntry() == null ? null : order.getPayEntry().value);
        in.setPayType(order.getPayType() == null ? null : order.getPayType().value);
        in.setRemark(order.getRemark());
        in.setPayTerminal(order.getPayTerminal() == null ? null : order.getPayTerminal().code);
        in.setOrderPayNumber(order.getOrderPayNumber());
        in.setMbrRechargeRuleId(order.getMbrRechargeRuleId() == null ? null : order.getMbrRechargeRuleId().getId());

        in.setId(order.getId() == null ? null : order.getId().getId());
        return in;
    }
}
